TC Portal - Core Business Context
TC Portal - Core Business Context
This document provides essential context about the Trilogy Care Portal for AI-assisted feature planning.
Business Overview
What We Do
Trilogy Care Portal is a comprehensive care management system for the Support at Home (SAH) program, managed by Services Australia. We help care providers manage:
- Participant packages and funds
- Service planning and delivery
- Budget management and allocation
- Billing and invoicing
- Compliance and reporting
Key Stakeholders
| Role | Count | Primary Responsibilities | Technical Access Level |
|---|---|---|---|
| Recipients | 11000+ | Receive care services; indirect system users | None (future: portal access) |
| Care Coordinators | 350+ | Manage participant budgets, create service plans, coordinate care | Read/Write (package-level) |
| Case Managers (Care Partners) | 60+ | Supervise multiple recipients, liaise and supervise care coordinators approve budgets, monitor outcomes | Read/Write (caseload-level) |
| System Administrators | 20+ | Configure system, manage users, troubleshoot issues | Full admin access |
| Finance/Accounting | 50+ | Reconcile funding, generate reports, audit transactions | Read (financial data) |
| Suppliers/Service Providers | 24000+ | Deliver services, submit invoices | Limited (supplier portal) |
User Personas
Sarah - Care Coordinator
- Age: 35, 5 years experience
- Tech Comfort: Medium (proficient with web apps, not technical)
- Daily Tasks: Create budget plans, schedule services, communicate with participants, track utilization
- Pain Points: Too many manual processes, hard to track funding across quarters, reconciliation headaches
- Needs: Simple UI, clear visibility into funding, automation of repetitive tasks
Michael - Case Manager
- Age: 42, 10 years experience
- Tech Comfort: Medium-High (power user, not developer)
- Daily Tasks: Review budget plans, approve submissions, generate reports, monitor team performance
- Pain Points: Lack of real-time dashboards, manual report generation, unclear funding status
- Needs: Executive dashboards, bulk operations, comprehensive reporting
Admin - System Administrator
- Age: 28, technical background
- Tech Comfort: High (comfortable with databases, APIs, configuration)
- Daily Tasks: Configure system settings, troubleshoot issues, manage integrations, monitor performance
- Pain Points: Limited admin UI, requires developer for some configs
- Needs: Comprehensive admin panel, logs, monitoring tools
Technical Architecture
Stack
- Backend: Laravel 12 (PHP 8.4+)
- Frontend: Vue 3 + Inertia.js + TypeScript
- Database: MySql
- Queue: Redis + Laravel Horizon
- Event Sourcing: Spatie Laravel Event Sourcing
Domain-Driven Design Structure
/domain /Budget (Budget plans, allocations, items) /Funding (Funding streams, fundings, quarters) /Package (Participant packages, needs, levels) /Billing (Invoices, claims, bill items) /Supplier (Service providers, services) /User (Users, roles, permissions)
/app-modules /api/src/V1 (API endpoints)
/resources /js/Pages (Vue Inertia pages) /js/Components (Vue components)Key Domain Models
Package
Represents a participant’s care package with funding and service entitlements.
id,external_id,participant_id,status,package_level_id,commencement_date,end_date- Relationships:
participant,packageLevel,fundings,budgetPlans,needs
FundingStream
Types of funding available (ON, RC, EL, AT, HM, CU, HC, VC).
id,external_id,name,colour,is_visible,is_services_australia,gl_code- Computed:
is_expirable,is_contribution_applicable
Funding
Services Australia approved funding for a package and funding stream.
id,external_id,package_id,funding_stream_id,start_date,end_dateservices_australia_total_amount,services_australia_available_amount,services_australia_used_amountallocated_amount,used_services_amount,used_fees_amount
BudgetPlan
Draft or active budget plan for a package, detailing how funding will be spent.
uuid,package_id,status(DRAFT, SUBMITTED, IN_REVIEW, ACTIVE, REJECTED, ARCHIVED)commencement_quarter_id,submitted_by,coordinator_loading_fee- Relationships:
fundingStreams,items,quarters
BudgetPlanFundingStream
Funding stream allocation within a budget plan.
id,budget_plan_uuid,funding_id,funding_stream_id,start_date,end_datetotal_amount,allocated_amount,source(PORTAL_APP or API_V1)
BudgetPlanItem
Line item in a budget plan (e.g., “Personal care - 3x per week”).
uuid,budget_plan_uuid,service_id,supplier_id,frequency,quantityestimated_services_amount,estimated_tc_fees_amount,estimated_cc_fees_amount
Quarter
13-week period for funding allocation.
id,start_date,end_date,name(e.g., “Q1 2025”)
Event Sourcing
We use event sourcing for critical business logic to ensure:
- Complete audit trail
- State rebuilding from events
- Compliance with regulations
Aggregate Roots
BudgetPlanAggregateRoot(domain/Budget/EventSourcing/Aggregates)FundingAggregateRoot(domain/Funding/EventSourcing/Aggregates)
Key Events
BudgetPlanCreated,BudgetPlanSubmitted,BudgetPlanActivatedBudgetPlanFundingStreamAdded,BudgetPlanFundingStreamUpdatedFundingSyncedEvent
Pattern
$aggregateRoot = BudgetPlanAggregateRoot::retrieve($uuid);$aggregateRoot->createBudgetPlan($data) ->submitBudgetPlan($submittedBy) ->persist();Laravel Data Usage
We use Spatie Laravel Data extensively for DTOs, validation, and transformation.
Pattern
use Spatie\LaravelData\Data;
class CreateBudgetPlanData extends Data{ public function __construct( public int $packageId, public int $commencementQuarterId, public ?float $coordinatorLoadingFee, /** @var array<BudgetPlanItemData> */ public array $items, ) {}
public static function rules(): array { return [ 'packageId' => ['required', 'exists:packages,id'], 'commencementQuarterId' => ['required', 'exists:quarters,id'], 'coordinatorLoadingFee' => ['nullable', 'numeric', 'min:0'], 'items' => ['required', 'array', 'min:1'], ]; }}Benefits
- Type-safe DTOs
- Auto-validation
- Easy transformation (from request, to response, to model)
- Composable (nested Data objects)
Services Australia Integration
We sync data from Services Australia’s API:
- Package details
- Funding allocations
- Claims and payments
Sync Pattern
// Middleware pipeline pattern for syncingKey Points
- Services Australia is source of truth for funding
- We can draft funding streams locally, but SA approval required for activation
- Rollover managed by SA (default 60 days post-quarter)
Configuration-Driven Behavior
config/support-at-home.php
'allocation_rules' => [ 'SERG-0001' => ['EL', 'ON', 'RC', 'CU', 'HC', 'VC'], // Home Support 'SERG-0002' => ['CU', 'HC', 'AT', 'VC'], // Assistive Technology 'SERG-0003' => ['CU', 'HC', 'HM', 'VC'], // Home Modifications],'expirable_funding_streams' => ['ON'],'no_contribution_funding_streams' => ['CU'],Key Business Rules
Funding Allocation Priority
For Home Support services (SERG-0001):
- EL (End of Life) - Highest priority
- ON (Ongoing) - Primary funding
- RC (Restorative Care)
- CU (Commonwealth Unspent) - No client contributions
- HC (Home Care Account)
- VC (Voluntary Contribution)
Budget Plan Workflow
- DRAFT - Care coordinator creates plan
- SUBMITTED - Submitted for review
- IN_REVIEW - Case manager reviewing
- ACTIVE - Approved and active (only one active per package)
- REJECTED - Not approved
- ARCHIVED - Replaced by newer plan
Quarterly Allocation
- Budgets broken down by quarter
- Consumption tracked per quarter
- Underspend notifications at 33%, 66%, 85% thresholds (days 31-45, 61-75, 76-90)
UI/UX Patterns
Inertia.js Pages
- Server-side rendering with Vue components
- No API calls from frontend (Inertia handles data passing)
- Form submissions via Inertia form helpers
Component Library
- Headless UI for accessible components
- Tailwind CSS for styling
- Custom components in
/resources/js/Components
Common Patterns
- Forms: UseForm from Inertia, Laravel Data on backend
- Tables: Server-side pagination, sorting, filtering
- Modals: Headless UI Dialog
- Notifications: Toast system (custom)
Permissions and Authorization
Roles
super_adminadmincase_managercare_coordinatorsupplierfinance_user
Pattern
// GatesGate::define('view-budget-plan', function (User $user, BudgetPlan $budgetPlan) { return $user->can('view-package', $budgetPlan->package);});
// Policiesclass BudgetPlanPolicy{ public function update(User $user, BudgetPlan $budgetPlan): bool { return $budgetPlan->status === BudgetPlanStatus::DRAFT && $user->can('manage-package', $budgetPlan->package); }}Testing
Structure
- Unit tests in
/tests/Unit - Feature tests in
/tests/Feature - E2E tests in
/e2e
Pattern
use Tests\TestCase;
class CreateBudgetPlanTest extends TestCase{ use RefreshDatabase;
/** @test */ public function care_coordinator_can_create_budget_plan() { $user = User::factory()->careCoordinator()->create(); $package = Package::factory()->create();
$response = $this->actingAs($user) ->post(route('budget-plans.store'), [ 'package_id' => $package->id, 'commencement_quarter_id' => 1, 'items' => [...] ]);
$response->assertRedirect(); $this->assertDatabaseHas('budget_plans', [...]); }}Jobs and Queues
Pattern
namespace Domain\Funding\Jobs;
use Illuminate\Bus\Queueable;use Illuminate\Contracts\Queue\ShouldQueue;
class ProcessQuarterEndRolloversJob implements ShouldQueue{ use Queueable;
public function __construct( public Quarter $quarter ) {}
public function handle( IdentifyFundingRolloversAction $identifyAction, CalculateFundingRolloverAction $calculateAction, CreateFundingRolloverAction $createAction ): void { // Job logic with dependency injection }}Monitoring
- Laravel Horizon for queue monitoring
- Jobs logged with context
Notifications
Pattern
use Illuminate\Notifications\Notification;
class RolloverCreatedNotification extends Notification{ public function via($notifiable): array { return ['mail', 'database']; }
public function toMail($notifiable): MailMessage { return (new MailMessage) ->subject('Funding Rollover Created') ->line('A rollover has been created...') ->action('View Details', route('packages.show', $this->package)); }}API Structure
Versioning
/api/v1/*- All API routes versioned- Controllers in
/app-modules/api/src/V1/src/Http/Controllers
Pattern
namespace AppModules\Api\V1\Http\Controllers\Budget;
class BudgetPlanController extends Controller{ public function store( CreateBudgetPlanRequest $request, CreateBudgetPlanAction $action ): JsonResponse { $budgetPlan = $action->execute( CreateBudgetPlanData::from($request) );
return response()->json($budgetPlan, 201); }}Key Files to Reference
When planning features, often reference:
/config/support-at-home.php- Business rules/domain/*/Models/*.php- Domain models/domain/*/Actions/*.php- Business logic/domain/*/EventSourcing/Aggregates/*.php- Event sourcing/app-modules/api/src/V1/src/Http/Controllers/*- API endpoints/resources/js/Pages/*- UI pages/database/migrations/*- Schema
Common Feature Patterns
Adding a New Feature
- Database: Create migration for new tables/columns
- Model: Create Eloquent model in appropriate domain
- Data: Create Laravel Data DTOs for input/output
- Action: Create action classes for business logic
- Event Sourcing (if needed): Add events and update aggregate root
- API: Add controller and routes
- UI: Create Inertia page and Vue components
- Jobs (if async): Create queue jobs
- Notifications: Add notification classes
- Tests: Unit + feature tests
- Documentation: Update relevant docs
Compliance and Audit
Requirements
- Full audit trail for financial transactions
- Event sourcing for state changes
- Soft deletes (no hard deletes)
- User action logging
- Reconciliation with Services Australia
Pattern
// Audit log entryAuditLog::create([ 'user_id' => auth()->id(), 'action' => 'budget_plan_submitted', 'model_type' => BudgetPlan::class, 'model_id' => $budgetPlan->uuid, 'before' => $before, 'after' => $after, 'ip_address' => request()->ip(),]);Feature Flags
We use feature flags for gradual rollout:
return [ 'funding_rollover' => [ 'enabled' => env('FEATURE_FUNDING_ROLLOVER', false), 'rollout_percentage' => 0, // 0-100 ],];
// Usageif (Features::enabled('funding_rollover')) { // New feature code}Performance Considerations
- Use database indexes for common queries
- Eager load relationships to avoid N+1
- Queue long-running jobs
- Cache static data (funding streams, quarters)
- Optimize API responses (only return needed fields)
Monitoring and Logging
- Laravel Log (daily rotation)
- Sentry for error tracking
- Nightwatch for production metrics and logging
This context should be referenced when planning any new feature for the TC Portal.